package com.sykj.util;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.wxpay.sdk.WXPayUtil;
import com.sykj.config.WeChatConfig;
import com.sykj.entity.OrderMaster;
import com.sykj.service.IOrderMasterService;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName WeChatUtils
 * @Description TODO 微信支付帮助类
 * @Author vains
 * @Date 2019/6/30 18:15
 * @Version 1.0
 **/
@Component
public class WeChatUtils {

    @Autowired
    private WeChatConfig weChatConfig;

    @Autowired
    private IOrderMasterService masterService;

    /**
     * 微信支付
     * @Author vains
     * @Date 2019/6/30 22:20
     * @param body 商品信息
     * @param money 金额
     * @param out_trade_no 订单号， 全局唯一
     * @return java.util.Map<java.lang.String,java.lang.String>
     **/
    public static Map<String, String> wxPay(String body, String money, String out_trade_no) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("mch_id", WeChatConfig.MCHID);
        map.put("body", body);
        map.put("out_trade_no", out_trade_no);
        map.put("total_fee", money);
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        map.put("mch_create_ip", "127.0.0.1");
        map.put("callback_url", "http://vains.easy.echosite.cn/#/order?orderId="+out_trade_no);
        map.put("notify_url", WeChatConfig.NOTIFY_URL);
        map.put("service", "pay.weixin.jspay");
        map.put("is_raw", "1");
        String sign = null;
        try {
            sign = WXPayUtil.generateSignature(map, WeChatConfig.KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put("sign", sign);
        String post = HttpClientUtils.doPost(WeChatConfig.GATEWAY, map);
        System.out.println(post);
        Map<String, String> stringMap = null;
        try {
            stringMap = WXPayUtil.xmlToMap(post);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringMap;
    }

    /**
     * 解析request中的xml
     * @param request
     * @return
     */
    public static Map<String, String> parseRequest(HttpServletRequest request){

        Map<String, String> result = null;

        StringBuffer sb = new StringBuffer();

        //通过request获取流
        try (
                InputStream inputStream = request.getInputStream();
                BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        )
        {

            String s;

            while ((s = in.readLine()) != null) {

                sb.append(s);

            }

            String xml = sb.toString();

            System.out.println(xml);

            result = WXPayUtil.xmlToMap(xml);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;

    }

    /**
     * 微信退款
     * @Author vains
     * @Date 2019/6/30 22:19
     * @param money 退款金额
     * @param out_trade_no 订单号
     * @return java.util.Map<java.lang.String,java.lang.String>
     **/
    public static Map<String, String> cancel(String money, String out_trade_no) {
        System.out.println("微信退款开始...............................");
        Map<String, String> resultMap = null;
        try {
            Map<String, String> map = new HashMap<String, String>();
            map.put("mch_id", WeChatConfig.MCHID);
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            map.put("total_fee", money);
            map.put("out_trade_no", out_trade_no);
            map.put("out_refund_no", out_trade_no);
            map.put("refund_fee", money);
            map.put("op_user_id", WeChatConfig.MCHID);
            map.put("callback_url", "http://vains.easy.echosite.cn/#/order");
            map.put("service", "unified.trade.refund");
            String sign = WXPayUtil.generateSignature(map, WeChatConfig.KEY);
            map.put("sign", sign);
            String post = HttpClientUtils.doPost(WeChatConfig.GATEWAY, map);
            System.out.println(post);
            resultMap = WXPayUtil.xmlToMap(post);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }

    /**
     * 返回登录url
     * @Author vains
     * @Date 2019/7/1 0:17
     * @param orderId 订单id
     * @param callBack 回调地址
     * @return java.lang.String
     **/
    public static String getLoginUrl(String orderId, String callBack){
        try {
            return "https://open.weixin.qq.com/connect/oauth2/authorize" +
                    "?appid="+ HttpClientUtils.APPID +
                    "&redirect_uri="+ URLEncoder.encode(callBack, "utf-8") +
                    "&response_type=code&scope=snsapi_base" +
                    "&state=" + orderId +
                    "#wechat_redirect";
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据openid获取用户信息
     * @Author vains
     * @Date 2019/7/1 0:33
     * @param openid 微信用户openid， 类似于微信用户在公众号下的唯一标识
     * @return java.lang.String
     **/
    public static String getUserInfo(String openid){
        String token = getAccToken(HttpClientUtils.APPID, HttpClientUtils.APPSECRET);
        return HttpClientUtils.doGet("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + token + "&openid="+openid+"&lang=zh_CN");
    }

    /**
     * 获取用户头像
     * @Author vains
     * @Date 2019/7/1 0:39
     * @param userInfo 通过openid获取的用户信息
     * @return java.lang.String
     **/
    public static String getHeadImage(String userInfo){
        ObjectMapper mapper = new ObjectMapper();
        String imgUrl = null;
        try {
            Map map = mapper.readValue(userInfo, Map.class);
            imgUrl = (String) map.get("headimgurl");
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(imgUrl);
        return imgUrl;
    }

    /**
     * 获取access_token
     * @Author vains
     * @Date 2019/7/1 0:31
     * @param appId 公众号id
     * @param appSecret 公众号秘钥
     * @return java.lang.String
     **/
    private static String getAccToken(String appId, String appSecret){
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
        String result = HttpClientUtils.doGet(url);
        ObjectMapper mapper = new ObjectMapper();
        String accToken = "";
        try {
            JsonNode tree = mapper.readTree(result);
            accToken = tree.get("access_token").asText();
            if (accToken == null || "".equals(accToken)) {
                return "";
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return accToken;
    }

    /**
     * 根据openid发送消息
     * @Author vains
     * @Date 2019/7/1 8:37
     * @param openid 用户唯一标识
     * @return void
     **//*
    public static void sendOrder(String openid){
        MessageHelper message = new MessageHelper();
        message.setMsgtype("text");
        message.setDescription("订单支付成功，请注意查看");
        message.setTitle("阿香点餐");
        List<String> toUser = new ArrayList<>();
        toUser.add(openid);
        toUser.add(openid);
        message.setTouser(toUser);
        MessageHelper.TextBean textBean = new MessageHelper.TextBean();
        textBean.setContent("<a href='www.baidu.com'>点击查看订单</a>");
        message.setText(textBean);
        ObjectMapper mapper = new ObjectMapper();
        try {
            String string = mapper.writeValueAsString(message);
            String accToken = getAccToken(HttpClientUtils.APPID, HttpClientUtils.APPSECRET);
            String post = HttpClientUtils.doPost("https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=" + accToken, string);
            System.out.println(post);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }*/

    /**
     * 根据模板id发送消息
     * @Author vains
     * @Date 2019/7/1 11:36
     * @param orderId 订单编号
     * @return void
     **/
    public void sendOrderByTemplate(String orderId){
        OrderMaster master = masterService.getById(orderId);
        // 封装模板消息对象
        TemplateMessageHelper message = new TemplateMessageHelper();
        // 设置接收人openid
        message.setTouser(master.getBuyerOpenid());
        // 设置点击之后跳转的url
        message.setUrl("http://vains.easy.echosite.cn/#/order?orderId="+master.getOrderId());
        // 设置模板id
        message.setTemplate_id(weChatConfig.getTemplateId());
        TemplateMessageHelper.DataBean dataBean = new TemplateMessageHelper.DataBean();
        // 将订单对象中的数据copy到dataBean中
        BeanUtils.copyProperties(master, dataBean);
        // 设置模板中的数据
        message.setData(dataBean);
        // 利用ObjectMapper将对象转为json对象
        ObjectMapper mapper = new ObjectMapper();
        try {
            String string = mapper.writeValueAsString(message);
            // 通过APPID和APPSECRET获取access_token
            String accToken = getAccToken(HttpClientUtils.APPID, HttpClientUtils.APPSECRET);
            // 发送消息
            String post = HttpClientUtils.doPost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accToken, string);
            System.out.println(post);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

}
